﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NTFS
{
    public class Indice
    {
        public Indice()
        {
            mfts = new List<Mft>();
            if(File.Exists(Constantes.ARQ))
                CarregaIndice();            
        }
        private List<Mft> mfts;

        /// <summary>
        /// Adiciona novo elemento no indice do sistema de arquivo.
        /// </summary>
        /// <param name="mft"></param>
        public void AdicionaMFT(Mft mft)
        {
            if(mfts.Any(x=>x.Id == mft.Id))
            {
                for (int i = 0; i < mfts.Count; i++)
                {
                    if(mfts[i].Id == mft.Id)
                    {
                        mfts[i] = mft;
                        break;
                    }
                }
            }
            else
            {
                mfts.Add(mft);
            }
            GravaIndice();
        }

        public void RemoveMFT(Mft mft)
        {
            mfts.Remove(mfts.First<Mft>(x=>x.Id == mft.Id));
            GravaIndice();
        }

        //Pega mft do arquivo pos nome.
        public Mft PegaMft(string s)
        {
            CarregaIndice();
            foreach (Mft mft in mfts)
            {
                if(mft.Nome.CompareTo(s)==0)
                {
                    return mft;
                }
            }
            return null;
        }
        /// <summary>
        /// Pega o mft do arquivo pelo id.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Mft PegaMft(int id)
        {
            CarregaIndice();
            foreach (Mft mft in mfts)
            {
                if (mft.Id == id)
                {
                    return mft;
                }
            }
            return null;
        }

        /// <summary>
        /// Atualiza no objeto os indices do sistema de arquivo.
        /// </summary>
        public void CarregaIndice()
        {
            mfts = new List<Mft>();
            Mft info = new Mft();
            FileStream fs = new FileStream(Constantes.ARQ, FileMode.Open);
            StreamReader r = new StreamReader(fs);
            string str = r.ReadLine();
            string s="";
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] == '>')
                {
                    info = new Mft();
                    s = "";
                    bool nome = false;
                    for (; !nome; i++)
                    {
                        if (str[i] != ';' && str[i] != '>')
                        {
                            s += str[i];
                        }
                        else if (str[i] != '>')
                            nome = true;
                    }
                    
                    if (nome)
                    {
                        info.Nome = s;
                        info.Users = new List<user>();
                        int j = i;
                        //le os usuarios e permissoes
                        while (true)
                        {
                            user usr = new user();
                            usr.permissoes = Convert.ToInt32(str[j].ToString());
                            j++;
                            while (str[j] != ',' && str[j] != ';')
                            {
                                usr.nome = usr.nome + str[j];
                                j++;
                            }
                            info.Users.Add(usr);
                            j++;
                            if (str[j - 1] == ';')
                            {
                                break;
                            }
                        }
                        //le clusters usados
                        List<int> cl = new List<int>();
                        while (true)
                        {
                            if (str[j] == ';')
                                break;
                            cl.Add(Convert.ToInt32(str[j].ToString() + str[j + 1].ToString() + str[j + 2].ToString()));
                            j = j + 3;
                            if (str[j] == ',')
                                j++;
                        }
                        j++;
                        info.Tipo = str[j++];
                        j++;
                        string aux = "";
                        while(str[j]!=';' && str[j]!=']' && str[j]!='>')
                        {
                            aux += str[j++];
                        }
                        info.Id = Convert.ToInt32(aux);
                        info.Clusters = cl;
                        nome = false;
                        mfts.Add(info);
                        i = j-1;
                    }
                }
                if (str[i] == ']')
                    break;
            }
            r.Close();
            fs.Close();            
        }

        //000[>$~;6sistema;d;0;-1>$mft;6sistema;002;a;1;0>$bitmap;6sistema;001;a;2;0]
        /// <summary>
        /// Atualiza indice.
        /// </summary>
        public void GravaIndice()
        {
            StreamReader sr = new StreamReader(Constantes.ARQ);
            StringBuilder sb = new StringBuilder("");
            StringBuilder sb1 = new StringBuilder("");
            foreach(Mft mft in mfts)
            {
                sb1.Append(mft.Notacao());
            }
            sb.Append("000["+sb1.ToString()+"]\n");
            sr.ReadLine();
            sb.Append(sr.ReadToEnd());
            sr.Close();
            StreamWriter sw = new StreamWriter(Constantes.ARQ);
            sw.Write(sb.ToString());
            sw.Close();           
        }

    }
}
